package com.dragon.logical.service.contract.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.dragon.common.model.ResultCode;
import com.dragon.common.model.exception.CustomException;
import com.dragon.repository.entity.*;
import com.dragon.repository.mapper.*;
import com.dragon.logical.service.contract.IRefundService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * <p>
 * 退款表 服务实现类
 * </p>
 *
 * @author sy
 * @since 2024-01-09
 */
@Service
public class RefundServiceImpl extends ServiceImpl<RefundMapper, Refund> implements IRefundService {

    @Autowired
    RefundMapper mapper;

    @Autowired
    RefundProductMapper refundProductMapper;

    @Autowired
    ProduceProductsMapper produceProductsMapper;

    @Autowired
    ContractMapper contractMapper;

    @Autowired
    PlanCollectMapper planCollectMapper;

    @Autowired
    BillMapper billMapper;

    @Autowired
    BillCustomerMapper billCustomerMapper;


    @Override
    public Page<Refund> selectPageList(String contractCode, String customerName, String startTime, String endTime, Integer status, Integer page, Integer limit){

        Page<Refund> refundPage = new Page<>(page,limit);

        QueryWrapper<Refund> refundQueryWrapper = new QueryWrapper<>();

        refundQueryWrapper
                .like(StrUtil.isNotBlank(contractCode),"dc.num",contractCode)
                .like(StrUtil.isNotBlank(customerName),"dc2.customer_name",customerName)
                .eq(status != null,"dr.status",status)
                .ge(StrUtil.isNotBlank(startTime),"dc.create_time",startTime)
                .le(StrUtil.isNotBlank(startTime),"dc.create_time",endTime)
                .lt("dr.status",3);

        Page<Refund> refundPage1 = mapper.selectPageList(refundPage,refundQueryWrapper);

        return refundPage1;
    }


    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public AddPageData addRefund(Refund refund){

        // 插入主表信息
        refund.setCreateTime(DateUtil.date());
        mapper.insert(refund);
        // 插入子表信息

        if(refund.getRefundProducts().size() == 0){
            throw new CustomException(ResultCode.REFUND_PRODUCT_IS_NOT_FUND);
        }

        // 查询产品详情
        List<ProduceProducts> produceProducts = produceProductsMapper.selectList(
                new LambdaQueryWrapper<ProduceProducts>()
                        .eq(ProduceProducts::getProduceId,refund.getProduceId()));

        refund.getRefundProducts().forEach(refundProduct -> {

            ProduceProducts produceProducts1 = produceProducts.stream()
                    .filter(
                            i->i.getProduceId().equals(refund.getProduceId()) && i.getQuotesProductId().equals(refundProduct.getProductId())
                    ).findFirst().get();
            // 发货数量-退货数量-当前退货的数量
            if(produceProducts1.getDeliverNum() - produceProducts1.getRejectedNum() - refundProduct.getRefundNum() < 0){
                throw new CustomException(ResultCode.REFUND_PRODUCT_NUE_MAX);
            }
            // 对比产品数据是否可以退款
            refundProduct.setRefundId(refund.getId());
            refundProductMapper.insert(refundProduct);

            // 修改当前生产单产品的数量
            Integer number = produceProducts1.getRejectedNum() +  refundProduct.getRefundNum();
            produceProducts1.setRejectedNum(number);
            produceProducts1.setUpdateTime(DateUtil.date());
            produceProductsMapper.updateById(produceProducts1);
        });

        AddPageData addPageData = new AddPageData();
        addPageData.setAdminId(refund.getRefundAdminId());
        addPageData.setCorrelationId(refund.getId());
        addPageData.setWorkflowJson(refund.getWorkflowJsonList());
        addPageData.setStreamType(16);
        addPageData.setTitle(refund.getTitle());
        addPageData.setExempt(refund.getExempt());

        return addPageData;
    }


    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public void updateRefund(Refund refund){
        Refund refund1 = mapper.selectOne(
                new LambdaQueryWrapper<Refund>().eq(Refund::getId,refund.getId()).lt(Refund::getStatus,3)
        );

        if(refund1 == null){
            throw new CustomException(ResultCode.DATA_NOT_FOUND);
        }

        refund.setUpdateTime(DateUtil.date());
        mapper.updateById(refund);

        //查询产品列表数据，并核对是否有一样的数据

        if(refund.getRefundProducts().size() == 0){
            throw new CustomException(ResultCode.REFUND_PRODUCT_IS_NOT_FUND);
        }

        // 查询生产单产品详情
        List<ProduceProducts> produceProducts = produceProductsMapper.selectList(
                new LambdaQueryWrapper<ProduceProducts>()
                        .eq(ProduceProducts::getProduceId,refund.getId()));

        //删除之前没有之前id的数据
        refundProductMapper.delete(new LambdaQueryWrapper<RefundProduct>().eq(RefundProduct::getRefundId,refund.getId()));
        refund.getRefundProducts().forEach(refundProduct -> {
            ProduceProducts produceProducts1 = produceProducts.stream()
                    .filter(
                            i->i.getProduceId() == refund.getProduceId() && i.getQuotesProductId()==refundProduct.getProductId()
                    ).findFirst().get();
            // 对比产品数据是否可以退款
            if(produceProducts1.getDeliverNum() - produceProducts1.getRejectedNum() - refundProduct.getRefundNum() < 0){
                throw new CustomException(ResultCode.REFUND_PRODUCT_NUE_MAX);
            }
            refundProduct.setRefundId(refund.getId());
            refundProductMapper.insert(refundProduct);

            // 修改当前生产单产品的数量
            Integer number = produceProducts1.getRejectedNum() +  refundProduct.getRefundNum();
            produceProducts1.setRejectedNum(number);
            produceProducts1.setUpdateTime(DateUtil.date());
            produceProductsMapper.updateById(produceProducts1);
        });
    }

    @Override
    public void updateStatus(Integer id, Integer status){
        Refund refund = mapper.selectOne(
                new LambdaQueryWrapper<Refund>().eq(Refund::getId,id).lt(Refund::getStatus,3)
        );
        if(refund == null){
            throw new CustomException(ResultCode.DATA_NOT_FOUND);
        }
        refund.setStatus(status);
        refund.setUpdateTime(DateUtil.date());
        mapper.updateById(refund);

        //删除或者作废时，直接剔除对应生产单的退款数量

        List<RefundProduct> refundProducts = refundProductMapper.selectList(
                new LambdaQueryWrapper<RefundProduct>().eq(RefundProduct::getRefundId,refund.getId())
        );

        refundProducts.forEach(refundProduct -> {
            // 查询当前生产单的对应产品
            ProduceProducts produceProducts = produceProductsMapper.selectOne(
                    new LambdaQueryWrapper<ProduceProducts>().eq(ProduceProducts::getProduceId,refund.getProduceId())
                            .eq(ProduceProducts::getQuotesProductId,refundProduct.getProductId())
            );
            if(produceProducts.getDeliverNum() - produceProducts.getRejectedNum() - refundProduct.getRefundNum() < 0){
                throw new CustomException(ResultCode.REFUND_PRODUCT_NUE_MAX);
            }
            //修改对应生产单的退货数量
            Integer number = produceProducts.getRejectedNum() - refundProduct.getRefundNum();
            produceProducts.setRejectedNum(number);
            produceProducts.setUpdateTime(DateUtil.date());
            produceProductsMapper.updateById(produceProducts);
        });

        //如果是作废则直接减去当前退款金额，应收账单金额
        if(status == 3){
            //修改合同总金额
            Contract contract = contractMapper.selectById(refund.getContractId());
            Double refundMoney = contract.getRefundMoney() - refund.getRefundMoney();

            contract.setRefundMoney(refundMoney);
            contract.setUpdateTime(DateUtil.date());
            contractMapper.updateById(contract);

            //修改应收账单中应收金额
            PlanCollect planCollect = planCollectMapper.selectOne(
                    new LambdaQueryWrapper<PlanCollect>().eq(PlanCollect::getContractId,refund.getContractId()).eq(PlanCollect::getPlanPayType,0)
            );
            if(planCollect != null){
                planCollect.setRefundMoney(refundMoney);
                planCollect.setUpdateTime(DateUtil.date());
                planCollectMapper.updateById(planCollect);

                //如果当前应收账单有对账单的话，则直接删除对账单的金额本期和累计
                if(planCollect.getBillStatus()==1){
                    Bill bill = billMapper.selectById(planCollect.getBillId());
                    //累计金额处理
                    BillCustomer billCustomer =  billCustomerMapper.selectOne(
                            new LambdaQueryWrapper<BillCustomer>().eq(BillCustomer::getCustomerId,bill.getCustomerId())
                    );
                    // 如果是已经完成的账单,则加上2个金额
                    Double planMoney = bill.getPlanMoney() + refund.getRefundMoney();
                    //本期应收
                    bill.setPlanMoney(planMoney);
                    //累计应收金额
                    Double accruedPlanMoney = billCustomer.getAccruedPlanMoney() + refund.getRefundMoney();
                    billCustomer.setAccruedPlanMoney(accruedPlanMoney);
                    if(bill.getIsFinish() == 1){
                        //本期实收
                        Double paymentMoney = bill.getPlanMoney() + refund.getRefundMoney();
                        bill.setPaymentMoney(paymentMoney);

                        //累计实收金额
                        Double accruedPaymentMoney = billCustomer.getAccruedPaymentMoney() + refund.getRefundMoney();
                        billCustomer.setAccruedPaymentMoney(accruedPaymentMoney);
                    }
                    billMapper.updateById(bill);
                    billCustomerMapper.updateById(billCustomer);
                }
            }
        }

    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void auditStatus(Integer id, Integer status){
        // 审批流程通过，修改主表信息
        Refund refund = mapper.selectOne(
                new LambdaQueryWrapper<Refund>().eq(Refund::getId,id).lt(Refund::getStatus,3)
        );
        if(refund == null){
            throw new CustomException(ResultCode.DATA_NOT_FOUND);
        }
        refund.setStatus(status);
        refund.setUpdateTime(DateUtil.date());
        mapper.updateById(refund);

        // 审核通过的话则直接修改生产单中退货数量
        List<RefundProduct> refundProducts = refundProductMapper.selectList(
                new LambdaQueryWrapper<RefundProduct>().eq(RefundProduct::getRefundId,refund.getId())
        );

        if(status == 1){

            refundProducts.forEach(refundProduct -> {
                // 查询当前生产单的对应产品
                ProduceProducts produceProducts = produceProductsMapper.selectOne(
                        new LambdaQueryWrapper<ProduceProducts>().eq(ProduceProducts::getProduceId,refund.getProduceId())
                                .eq(ProduceProducts::getQuotesProductId,refundProduct.getProductId())
                );
                //修改对应生产单的退货数量
                Integer number = produceProducts.getRejectedNum() + refundProduct.getRefundNum();
                produceProducts.setRejectedNum(number);
                produceProducts.setUpdateTime(DateUtil.date());
                produceProductsMapper.updateById(produceProducts);
            });

            //修改合同总金额
            Contract contract = contractMapper.selectById(refund.getContractId());
            Double refundMoney = contract.getRefundMoney() + refund.getRefundMoney();

            contract.setRefundMoney(refundMoney);
            contract.setUpdateTime(DateUtil.date());
            contractMapper.updateById(contract);

            //修改应收账单中应收金额
            PlanCollect planCollect = planCollectMapper.selectOne(
                    new LambdaQueryWrapper<PlanCollect>().eq(PlanCollect::getContractId,refund.getContractId()).eq(PlanCollect::getPlanPayType,0)
            );
            if(planCollect != null){
                if(planCollect.getPlanStatus() == 1){
                    Double actualPlanMoney = planCollect.getActualPlanMoney() - refund.getRefundMoney();
                    planCollect.setActualPlanMoney(actualPlanMoney);
                }
                planCollect.setRefundMoney(refundMoney);
                planCollect.setUpdateTime(DateUtil.date());
                planCollectMapper.updateById(planCollect);

                //如果当前应收账单有对账单的话，则直接删除对账单的金额本期和累计
                if(planCollect.getBillStatus()==1){
                    Bill bill = billMapper.selectById(planCollect.getBillId());
                    //累计金额处理
                    BillCustomer billCustomer =  billCustomerMapper.selectById(
                            new LambdaQueryWrapper<BillCustomer>().eq(BillCustomer::getCustomerId,bill.getCustomerId())
                    );
                    // 如果是已经完成的账单,则减去2个金额
                    Double planMoney = bill.getPlanMoney() - refund.getRefundMoney();
                    //本期应收
                    bill.setPlanMoney(planMoney);
                    //累计应收金额
                    Double accruedPlanMoney = billCustomer.getAccruedPlanMoney() - refund.getRefundMoney();
                    billCustomer.setAccruedPlanMoney(accruedPlanMoney);
                    if(bill.getIsFinish() == 1){
                        //本期实收
                        Double paymentMoney = bill.getPlanMoney() - refund.getRefundMoney();
                        bill.setPaymentMoney(paymentMoney);

                        //累计实收金额
                        Double accruedPaymentMoney = billCustomer.getAccruedPaymentMoney() - refund.getRefundMoney();
                        billCustomer.setAccruedPaymentMoney(accruedPaymentMoney);
                    }
                    billMapper.updateById(bill);
                    billCustomerMapper.updateById(billCustomer);
                }
            }
        } else {
            //如果未通过则删除退货数量
            refundProducts.forEach(refundProduct -> {
                // 查询当前生产单的对应产品
                ProduceProducts produceProducts = produceProductsMapper.selectOne(
                        new LambdaQueryWrapper<ProduceProducts>().eq(ProduceProducts::getProduceId,refund.getProduceId())
                                .eq(ProduceProducts::getQuotesProductId,refundProduct.getProductId())
                );
                if(produceProducts.getDeliverNum() - produceProducts.getRejectedNum() - refundProduct.getRefundNum() < 0){
                    throw new CustomException(ResultCode.REFUND_PRODUCT_NUE_MAX);
                }
                //修改对应生产单的退货数量
                Integer number = produceProducts.getRejectedNum() - refundProduct.getRefundNum();
                produceProducts.setRejectedNum(number);
                produceProducts.setUpdateTime(DateUtil.date());
                produceProductsMapper.updateById(produceProducts);
            });
        }
    }


    @Override
    public Refund selectDetailById(Integer id){
        //查询主表id
        Refund refund = mapper.selectDetailById(id);

        if(refund == null){
            throw new CustomException(ResultCode.DATA_NOT_FOUND);
        }
        //获取子表信息
        List<RefundProduct> refundProducts = refundProductMapper.selectProductDetailByList(id);

        refund.setRefundProducts(refundProducts);

        return refund;
    }

}
